//
//  NetworkTools.swift
//  SinaWeiBo
//
//  Created by gxiangzi on 15/9/4.
//  Copyright © 2015年 hqu. All rights reserved.
//

import UIKit
import AFNetworking
import ReactiveCocoa

enum RequestMethod : String {
    case GET = "GET"
    case POST = "POST"
}

class NetworkTools: AFHTTPSessionManager {
    
    // MARK: - 设置 网络通信的基本需求
    let appKey = "1234516330"
    let appSecret = "2ed0c35d537dc2d05d5d0110ee315d78"
    let backPage = "http://www.cnblogs.com/gaox97329498/"
    
     // MARK: - 单例对象
    static var sharedTools:NetworkTools = {
        
        var instance =  NetworkTools(baseURL: nil)
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        return instance
    }()
    
    // MARK - :发布一个微博
    /// - see: [http://open.weibo.com/wiki/2/statuses/update](http://open.weibo.com/wiki/2/statuses/update)
    /// - see: [http://open.weibo.com/wiki/2/statuses/upload](http://open.weibo.com/wiki/2/statuses/upload)
    func sendStatus(status:String,image:UIImage?) -> RACSignal
    {
        var paremeters = [String:AnyObject]()
        
        paremeters["status"] = status
        
        if image == nil
        {
           return request(.POST, urlString: "https://api.weibo.com/2/statuses/update.json", parameters: paremeters)
        }else
        {
            return upload(.POST, urlString: status, parameters: paremeters, image: image!)
        }

    }

    // MARK: - 获取微博
    func  loadStatus(since_id since_id: Int, max_id: Int) -> RACSignal {
        
        // 创建一个参数的数组
        var paremeters = [String : AnyObject]()
        
        let url = "https://api.weibo.com/2/statuses/home_timeline.json"
        
        if since_id > 0 {
            
            paremeters["since_id"] = since_id
            
        } else if max_id > 0 {
            
            paremeters["max_id"] = since_id
        }
        
         return request(.GET, urlString: url, parameters: paremeters, withToken: true)
    }
    
    
    
     // MARK: - 获取授权的ULR
    // get 方法
    var OauthUrl:NSURL {
         return NSURL(string: "https://api.weibo.com/oauth2/authorize?client_id=\(appKey)&redirect_uri=\(backPage)")!
    }
    
    /// 获取 AccessToken
    ///
    /// - parameter code: 请求码/授权码
    /// - see: [http://open.weibo.com/wiki/OAuth2/access_token](http://open.weibo.com/wiki/OAuth2/access_token)
    func loadAccessToken(code: String) -> RACSignal {
        let urlString = "https://api.weibo.com/oauth2/access_token"
        
        let params = ["client_id": appKey,
            "client_secret": appSecret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": backPage]
        
        return request(RequestMethod.POST, urlString: urlString, parameters: params,withToken:false)
    }
    
     // MARK: - 下载用户信息
    func loadUserInfo(uid : String) ->RACSignal {
        
        let urlString = "https://api.weibo.com/2/users/show.json"
        let params = ["uid": uid]
        
        return request(.GET, urlString: urlString, parameters: params, withToken:true)
    }

   
    private func appendToken( inout  parameters:[String:AnyObject]?) -> Bool {
        
        guard let token = UserAccountViewModel.sharedUserAccount.accessToken else {
            
            return false
        }
        
        if parameters == nil {
            
            parameters = [String:AnyObject]();
        }
        
        // 后续的 token 都是有值的
        parameters!["access_token"] = token
        
        return true
    }
   
    
    func request(method:RequestMethod,urlString:String,var parameters:[String:AnyObject]?,withToken:Bool = true)  -> RACSignal
    {
        
        return RACSignal.createSignal({ (subscriber) -> RACDisposable! in
                
                if withToken && !self.appendToken(&parameters)
                {
                    // 如果为空的话
                    subscriber.sendError(NSError(domain: "com.hqu.edu", code: -1000, userInfo: ["errorMessage" : "Token获取失败"]))
                    return nil
                }

        
            let successCallBack = {(task:NSURLSessionDataTask, result:AnyObject) -> Void in
                
                // 将结果发送给订阅者
                subscriber.sendNext(result)
                // 完成
                subscriber.sendCompleted()
            }
            
            let failCallBack = { (task: NSURLSessionDataTask, error :NSError) -> Void in
                print(error)
                subscriber.sendError(error)
            }
            
            if method == RequestMethod.GET
            {
                self.GET(urlString, parameters: parameters, success: successCallBack, failure:failCallBack)
            }else
            {
                self.POST(urlString, parameters: parameters, success: successCallBack, failure: failCallBack)
            }
            return nil;
            
        })
    }
    
    func upload(method:RequestMethod,urlString:String,var parameters:[String:AnyObject]?,image:UIImage) ->RACSignal
    {
        return RACSignal.createSignal(){ (subscriber) -> RACDisposable! in
            
            if !self.appendToken(&parameters)
            {
                // 如果为空的话
                subscriber.sendError(NSError(domain: "com.hqu.edu", code: -1000, userInfo: ["errorMessage" : "Token获取失败"]))
                return nil
            }

            let data = UIImagePNGRepresentation(image)!
            
            // AFMultipartFormData：是协议的方法
            // formData 是遵守协议的对象， AFN 内部提供的，使用的时候，按照参照协议的方法传递参数
            
            // formData 是遵守协议的对象，AFN内部提供的，使用的时候，只需要按照协议方法传递参数即可！
            /**
            1. 要上传图片的二进制数据
            2. 服务器的字段名，开发的时候，咨询后台
            3. 保存在服务器的文件名，很多后台允许随便写
            4. mimeType -> 客户端告诉服务器上传文件的类型，格式
            大类/小类
            image/jpg
            image/gif
            image/png
            如果，不想告诉服务器具体的类型，可以使用 application/octet-stream
            
            */

            
            self.POST(urlString, parameters: parameters, constructingBodyWithBlock: { (formData) -> Void in
                
                 formData.appendPartWithFileData(data, name: "pic", fileName: "ohoh", mimeType: "application/octet-stream")
                
                }, success: { (_, result) -> Void in
                    
                    subscriber.sendNext(result)
                    subscriber.sendCompleted()
                    
                }, failure: { (_, error) -> Void in
                    printLog(error, logError: true)
                    
                    subscriber.sendError(error)
                })
        
            return nil
        }
    }
}
